﻿
Imports std

Namespace internalFunctions

    'parameters, input, input object
    'return, bool, whether input is nothing / null
    Public Class isnull
        Inherits inputIFunction(Of bare_variable, Boolean)

        Private Shared a As aliases = Nothing

        Shared Sub New()
            initialAliases(a, "null")
        End Sub

        Public Sub New()
            MyBase.New("isnull", a)
        End Sub

        Protected Overrides Function invoke(ByVal i As bare_variable, ByRef o As Boolean) As Boolean
            o = i Is Nothing OrElse i.value() Is Nothing
            Return True
        End Function

        Protected Overrides Function finder() As iVariableFinder(Of bare_variable)
            Return bare_variable_finder()
        End Function

        Protected Overrides Function enableNoInput() As Boolean
            Return True
        End Function

        Protected Overrides Function returnType() As typeDefination
            Return typeDefination.bool
        End Function
    End Class

    'parameters, i, input object
    'return, bool, input.false()
    Public Class notlogic
        Inherits inputIFunction(Of Boolean, Boolean)

        Private Shared a As aliases = Nothing

        Shared Sub New()
            initialAliases(a, "!")
        End Sub

        Public Sub New()
            MyBase.New("not", a)
        End Sub

        Protected Overrides Function invoke(ByVal i As Boolean, ByRef o As Boolean) As Boolean
            o = Not (i)
            Return True
        End Function

        Protected Overrides Function finder() As iVariableFinder(Of Boolean)
            Return bool_finder()
        End Function

        Protected Overrides Function returnType() As typeDefination
            Return typeDefination.bool
        End Function
    End Class

    'parameters, i1, input object
    '            i2 ... in
    'return, bool, invokeImpl(i1-in)
    Public MustInherit Class multiboollogic
        Inherits internalFunction

        Public Class parameters
            Public Const ibase As String = "i"
        End Class

        Private Shared m As iParametersMapping = Nothing

        Shared Sub New()
            initialSerialMapping(m, parameters.ibase)
        End Sub

        Protected MustOverride Overloads Function invokeImpl(ByVal i1 As Boolean, ByVal i2 As Boolean) As Boolean
        Protected MustOverride Function initialvalue() As Boolean

        Protected Sub New(ByVal name As String)
            Me.New(name, Nothing)
        End Sub

        Protected Sub New(ByVal name As String, ByVal aliases As aliases)
            MyBase.New(name, m, aliases)
        End Sub

        Private Function callback(ByVal name As String, ByVal v As Boolean, ByRef rtn As Boolean) As Boolean
            rtn = invokeImpl(rtn, v)
            Return True
        End Function

        Protected NotOverridable Overrides Function invoke(ByVal ctx As context, _
                                                           ByRef output As bare_variable) As Boolean
            Dim rst As Boolean
            rst = initialvalue()
            If Not ctx.findVariables(AddressOf callback, string_finder, parameters.ibase, 0, rst) Then
                'match old version of scripts
                ctx.findVariables(AddressOf callback, string_finder, parameters.ibase, 1, rst)
            End If

            output = New bare_variable(typeDefination.bool, rst)
            Return True
        End Function
    End Class

    'parameters, same as multiboollogic
    'return, and i1-in
    Public Class andlogic
        Inherits multiboollogic

        Private Shared a As aliases = Nothing

        Shared Sub New()
            initialAliases(a, "&")
        End Sub

        Public Sub New()
            MyBase.New("and", a)
        End Sub

        Protected Overrides Function initialvalue() As Boolean
            Return True
        End Function

        Protected Overloads Overrides Function invokeImpl(ByVal i1 As Boolean, ByVal i2 As Boolean) As Boolean
            Return (i1 AndAlso i2)
        End Function
    End Class

    'parameters, same as multiboollogic
    'return, or i1-in
    Public Class orlogic
        Inherits multiboollogic

        Private Shared a As aliases = Nothing

        Shared Sub New()
            initialAliases(a, "|")
        End Sub

        Public Sub New()
            MyBase.New("or", a)
        End Sub

        Protected Overrides Function initialvalue() As Boolean
            Return False
        End Function

        Protected Overrides Function invokeImpl(ByVal i1 As Boolean, ByVal i2 As Boolean) As Boolean
            Return (i1 OrElse i2)
        End Function
    End Class

    'parameters, condition, bool
    '            i1, any
    '            i2, any
    'return, same as i1/i2, if condition is true, return i1, otherwise i2
    Public Class ifoperfunc
        Inherits internalFunction

        Public Class parameters
            Public Const condition As String = "condition"
            Public Const i1 As String = "i1"
            Public Const i2 As String = "i2"
        End Class

        Private Shared _aliases As aliases = Nothing
        Private Shared m As iParametersMapping = Nothing

        Shared Sub New()
            initialAliases(_aliases, "?:")
            initialMapping(m, parameters.condition, parameters.i1, parameters.i2)
        End Sub

        Public Sub New()
            MyBase.New("ifoper", m, _aliases)
        End Sub

        Private Shared Function findVariable2(ByVal ctx As context, ByVal para As String, _
                                              ByRef output As bare_variable) As Boolean
            If Not ctx.findVariable(para, output) Then
                raiseError("expect parameter " + para, errorHandle.errorType.user)
                Return False
            Else
                Return True
            End If
        End Function

        Protected Overrides Function invoke(ByVal ctx As context, ByRef output As bare_variable) As Boolean
            Dim condition As bare_variable = Nothing
            If ctx.findVariable(parameters.condition, condition) Then
                Dim i As bare_variable = Nothing
                If condition.true() Then
                    If Not findVariable2(ctx, parameters.i1, i) Then
                        Return False
                    End If
                Else
                    If Not findVariable2(ctx, parameters.i2, i) Then
                        Return False
                    End If
                End If
                output = New bare_variable(i)
                Return True
            Else
                raiseError("expect parameter " + parameters.condition, errorHandle.errorType.user)
                Return False
            End If
        End Function
    End Class
End Namespace
